// 流程控制
mod c02_while;
mod c03_loop;

fn main() {
    println!("Hello, world!");
}

// 基本使用
#[test]
fn learn01() {
    let n = 6;

    // if-else 存在多个符合条件的分支时，只有第一个分支会被执行
    if n % 4 == 0 {
        println!("number is divisible by 4");
    } else if n % 3 == 0 {
        println!("number is divisible by 3");
    } else if n % 2 == 0 {
        println!("number is divisible by 2");
    } else {
        println!("number is not divisible by 4, 3, or 2");
    }
}

// if 语句块
#[test]
fn learn02() {
    let condition = true;

    // if 语句块是表达式
    // 用 if 来赋值时，要保证每个分支返回的类型一样
    let number = if condition { 5 } else { 6 };

    println!("The value of number is: {}", number);
}

// for 循环
#[test]
fn learn03() {
    let len = 5;

    for num in 0..len {
        if num == len - 1 {
            print!("{}\n", num)
        } else {
            print!("{}, ", num)
        }
    }
}

// for 循环2
#[test]
fn learn0302() {
    // let arr = 0..=5;

    let mut list = vec![1, 2, 3, 4, 5];

    // for 语句块使用的集合会发生所有权转移
    // for item in list {
    //     println!("{}", item);
    // }
    // println!("{:?}", list);

    // 使用 引用 来遍历集合里的元素
    for item in &list {
        println!("{}", item);
    }
    println!("{:?}", list);

    // 使用 可变引用 来修改遍历时的元素
    for item in &mut list {
        // 此时需要解引用才能修改元素的值
        *item = *item + 1;
        println!("{}", item);
    }
    println!("{:?}", list);

    /*
        使用方法                         等价使用方式                                    所有权
    for item in collection         for item in IntoIterator::into_iter(collection)     转移所有权
    for item in &collection        for item in collection.iter()                       不可变借用
    for item in &mut collection    for item in collection.iter_mut()                   可变借用
    */
}

// for 循环3
#[test]
fn learn0303() {
    // 循环时获取下标
    let a = [4, 3, 2, 1];
    // `.iter()` 方法把 `a` 数组变成一个迭代器
    for (i, v) in a.iter().enumerate() {
        println!("{} -- {}", i, v);
    }

    for (i, v) in (11..15).into_iter().enumerate() {
        println!("{} -- {}", i, v);
    }

    // 可以忽略 for 的遍历元素
    for _ in 0..5 {
        print!("正在循环");
    }
}

// for 循环4
#[test]
fn learn0304() {
    // 两种 for 循环方式的比较
    // 第一种
    let collection = [1, 2, 3, 4, 5];
    for i in 0..collection.len() {
        let _item = collection[i];
        // ...
    }

    // 第二种
    for _item in collection {}
    /*
    第一种方式是循环索引，然后通过索引下标去访问集合，第二种方式是直接循环集合中的元素，优劣如下：
        性能：第一种使用方式中 collection[index] 的索引访问，会因为边界检查(Bounds Checking)导致运行时的性能损耗 —— Rust 会检查并确认 index 是否落在集合内，但是第二种直接迭代的方式就不会触发这种检查，因为编译器会在编译时就完成分析并证明这种访问是合法的
        安全：第一种方式里对 collection 的索引访问是非连续的，存在一定可能性在两次访问之间，collection 发生了变化，导致脏数据产生。而第二种直接迭代的方式是连续访问，因此不存在这种风险( 由于所有权限制，在访问过程中，数据并不会发生变化)。
    */
}
